// i.r(t), i.d(t, { default: () => AppPhaseModule })
import Module from "./Module"
import ApplicationData, { createApplicationData } from "../data/ApplicationData"
import { ApplicationLoadedMessage, AppPhaseChangeMessage, ApplicationChangeMessage } from "../message/app.message"
import Logger from "../utils/Logger"
import { phaseMin } from "../enum/phase.enum"
import { appTypeMin } from "../enum/appType.enum"

import EngineContext from "../EngineContext"
import MarketContext from "../MarketContext"

const c = new Logger("app-phase")
export default class AppPhaseModule extends Module {
  market: MarketContext
  appState: ApplicationData
  broadcast: EngineContext["broadcast"]
  tasks: Record<number, Promise<any>[]>
  constructor() {
    super()
    this.name = "app-phase"
  }
  async init(e: any, t: EngineContext) {
    this.market = t.market
    this.broadcast = t.broadcast.bind(t)
    this.tasks = e.tasks
    this.appState = createApplicationData()
    this.appState.phase = phaseMin.UNINITIALIZED
    this.appState.phaseTimes[phaseMin.UNINITIALIZED] = Date.now()
    this.appState.application = appTypeMin.SHOWCASE
    this.market.register(this, ApplicationData, this.appState)
    this.watchTasks(this.appState.phase)
    this.watchErrors()
    this.updateAppHeaders()
    this.bindings.push(this.appState.onPropertyChanged("application", () => this.updateAppHeaders()))
  }
  async watchTasks(e: number) {
    if (e >= phaseMin.PLAYING) return
    const t = e + 1
    try {
      await Promise.all(this.tasks[t])
    } catch (e) {
      this.error(e)
    }
    t === phaseMin.PLAYING && this.broadcast(new ApplicationLoadedMessage(this.appState.application)),
      this.appState.phase !== phaseMin.ERROR && e !== phaseMin.ERROR && (this.updateCurrentPhase(t), this.watchTasks(t))
  }
  async watchErrors() {
    try {
      await Promise.all(this.tasks[phaseMin.ERROR])
    } catch (e) {
      this.error(e)
    }
  }
  updateCurrentPhase(e: number) {
    this.appState.phase = e
    this.appState.phaseTimes[e] = Date.now()
    c.info(`${JSON.stringify(this.appState)}`)
    this.appState.commit()
    this.broadcast(new AppPhaseChangeMessage(e))
  }
  error(e: any) {
    this.appState.error = e
    this.updateCurrentPhase(phaseMin.ERROR)
  }
  updateActiveApp(e: string) {
    this.appState.application = e
    this.appState.commit()
    this.broadcast(new ApplicationChangeMessage(e))
  }
  getData() {
    return this.appState
  }
  updateAppHeaders() {}
}
